home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / asm / m8087.mac < prev    next >
Encoding:
Text File  |  1984-08-27  |  28.4 KB  |  823 lines

  1. ;**********************************************************************;
  2. ;                                                                      ;
  3. ;       M8087.MAC - File of macros which provide assembly level        ;
  4. ;                   software support for use of 8087 NDP with          ;
  5. ;                   the IBM personal computer.                         ;
  6. ;                                                                      ;
  7. ;**********************************************************************;
  8.  
  9. if1     ; do not include this file in any output listing
  10.  
  11. ;**********************************************************************;
  12. ;                                                                      ;
  13. ;       ESC_REG - "REG" parameter specifies ESC value.  Issue proper   ;
  14. ;                 ESC sequence depending on REG value.  PARAM is a     ;
  15. ;                 6-bit parameter whose upper 3-bits make up the       ;
  16. ;                 "xxx" bits in the ESC opcode (11011xxx) and lower    ;
  17. ;                 3-bits make up "yyy~ bits in source byte following   ;
  18. ;                 (using standard "mod" and "r/m" designators define   ;
  19. ;                 byte as "modyyyr/m").                                ;
  20. ;                                                                      ;
  21. ;**********************************************************************;
  22.  
  23. ESC_REG macro PARAM,REG
  24.         ;
  25.         ; We need to determine what "reg" field assignment correspnds with
  26.         ; the current value of REG.  This is used as the source for the
  27.         ; ESC operation.  PARAM is used directly in the ESC call.
  28.         ;
  29.         ife REG ; Decrement until REG = 0, then issue ESC sequence
  30.           ESC PARAM,AX          ; AX = 000b (see operand summary for 8088)
  31.         else
  32.           REG = REG - 1
  33.           ife REG
  34.             ESC PARAM,CX                ; CX = 001b
  35.           else
  36.             REG = REG - 1
  37.             ife REG
  38.               ESC PARAM,DX              ; DX = 010b
  39.             else
  40.               REG = REG - 1
  41.               ife REG
  42.                 ESC PARAM,BX            ; BX = 011b
  43.               else
  44.                 REG = REG - 1
  45.                 ife REG
  46.                   ESC PARAM,SP          ; SP = 100b
  47.                 else
  48.                   REG = REG - 1
  49.                   ife REG
  50.                     ESC PARAM,BP        ; BP = 101b
  51.                   else
  52.                     REG = REG - 1
  53.                     ife REG
  54.                       ESC PARAM,SI      ; SI = 110b
  55.                     else                ; If REG >= 7, assume 7
  56.                       ESC PARAM,DI      ; DI = 111b
  57.                     endif
  58.                   endif
  59.                 endif
  60.               endif
  61.             endif
  62.           endif
  63.         endif
  64. endm    ; Done with ESC_REG macro
  65.  
  66. ;**********************************************************************;
  67. ;                                                                      ;
  68. ;       CHECK_ST - Inputs parameter "ST(i)" and returns with REG=i     ;
  69. ;                                                                      ;
  70. ;**********************************************************************;
  71.  
  72. CHECK_ST macro P_ST
  73.         REG = -1                        ; Assume no match is found
  74.         ifidn <&P_ST>,<ST(0)>           ; Is i=0?
  75.           REG = 0
  76.         endif
  77.         ifidn <&P_ST>,<ST(1)>
  78.           REG = 1
  79.         endif
  80.         ifidn <&P_ST>,<ST(2)>
  81.           REG = 2
  82.         endif
  83.         ifidn <&P_ST>,<ST(3)>
  84.           REG = 3
  85.         endif
  86.         ifidn <&P_ST>,<ST(4)>
  87.           REG = 4
  88.         endif
  89.         ifidn <&P_ST>,<ST(5)>
  90.           REG = 5
  91.         endif
  92.         ifidn <&P_ST>,<ST(6)>
  93.           REG = 6
  94.         endif
  95.         ifidn <&P_ST>,<ST(7)>
  96.           REG = 7
  97.         endif
  98.         ifidn <&P_ST>,<st(0)>           ; Is i=0?
  99.           REG = 0
  100.         endif
  101.         ifidn <&P_ST>,<st(1)>
  102.           REG = 1
  103.         endif
  104.         ifidn <&P_ST>,<st(2)>
  105.           REG = 2
  106.         endif
  107.         ifidn <&P_ST>,<st(3)>
  108.           REG = 3
  109.         endif
  110.         ifidn <&P_ST>,<st(4)>
  111.           REG = 4
  112.         endif
  113.         ifidn <&P_ST>,<st(5)>
  114.           REG = 5
  115.         endif
  116.         ifidn <&P_ST>,<st(6)>
  117.           REG = 6
  118.         endif
  119.         ifidn <&P_ST>,<st(7)>
  120.           REG = 7
  121.         endif
  122.         ;
  123.         ; If i not between 0 or 7, see if actually an
  124.         ; "ST(i)" or "ST(I)" string, indicating use of
  125.         ; top of stack element
  126.         ;
  127.         ifidn <&P_ST>,<ST(i)>
  128.           REG = 0
  129.         endif
  130.         ifidn <&P_ST>,<ST(I)>
  131.           REG = 0
  132.         endif
  133.         ifidn <&P_ST>,<st(i)>
  134.           REG = 0
  135.         endif
  136.         ifidn <&P_ST>,<st(I)>
  137.           REG = 0
  138.         endif
  139. endm
  140.  
  141.  
  142. ;**********************************************************************;
  143. ;*                                                                     ;
  144. ;*      CHK_CONC - Simple macro that will automatically insert         ;
  145. ;*                 WAIT statements AFTER every 8087 instruction        ;
  146. ;*                 which accesses CPU main memory.  If variable        ;
  147. ;*                 "AUTOSYNC" <> 0, then these WAITs will be           ;
  148. ;*                 inserted (providing no concurrency but relieving    ;
  149. ;*                 the programmer from worrying about synchronizing    ;
  150. ;*                 data references.  If the user program sets          ;
  151. ;*                 AUTOSYNC to a zero value, then no WAITs are         ;
  152. ;*                 inserted after the instructions and it is           ;
  153. ;*                 the user's responsibility to ensure synchro-        ;
  154. ;*                 nization.                                           ;
  155. ;*                                                                     ;
  156. ;**********************************************************************;
  157.  
  158. CHK_CONC macro
  159.  
  160.         if AUTOSYNC
  161.                   WAIT                  ; Automatic syncronization
  162.         endif
  163. endm
  164.  
  165.  
  166.  
  167. ;**********************************************************************;
  168. ;                                                                      ;
  169. ;       CHOOSE_4 - Determine which of four parameters (XXX1 to XXX4)   ;
  170. ;                  should be used in ESC sequence, depending on P1     ;
  171. ;                  and P2 values.  P2 and P2 are parameters passed     ;
  172. ;                  by user in macro call.  XXX1 to XXX4 are macro-     ;
  173. ;                  dependent parameters tacked on to the call to       ;
  174. ;                  CHOOSE_4 by the specific 8087 macro called by the   ;
  175. ;                  user code.                                          ;
  176. ;                                                                      ;
  177. ;**********************************************************************;
  178.  
  179. CHOOSE_4 macro P1,P2,XXX1,XXX2,XXX3,XXX4
  180.  
  181.         ; Initialize variables
  182.         ZERO = 0
  183.         NOTZERO = 0
  184.         REG = 0
  185.         ;
  186.         ; If user passed no parameters, (P1 and P2 are "blank") then
  187.         ; issue a call to ESC_REG macro to set up proper ESC sequence.
  188.         ; An arithmetic instruction with no operands is identical to the
  189.         ; same instruction with the operand form "ST(1),ST".
  190.         ; Example: "FDIV" - Divides second element of stack by first and
  191.         ;                   places result in second element on stack.
  192.         ;
  193.         ifb <P1>
  194.                   REG = 1
  195.                   ESC_REG XXX1,REG
  196.         else
  197.         ;
  198.         ; Check to see if first parameter (P1) passed by user is "ST".
  199.         ; If yes, indecates that second parameter (P2) is of form "ST(i)"
  200.         ; so use CHECK_ST macro to determine 'i'.  Then call ESC_REG macro
  201.         ; to issue ESC sequence.
  202.         ; Example: "FADD ST,ST(4)" - Adds register four (fifth element on
  203.         ;                            8087 stack) to top element and leaves
  204.         ;                            result on top of stack.
  205.         ;
  206.         ifidn <P1>,<ST>
  207.           CHECK_ST P2
  208.           ZERO = REG + 1
  209.           ife ZERO
  210.             REG = 1
  211.           endif
  212.           ESC_REG XXX2,REG
  213.         else
  214.         ifidn <P1>,<st>
  215.           CHECK_ST P2
  216.           ZERO = REG + 1
  217.           ife ZERO
  218.             REG = 1
  219.           endif
  220.           ESC_REG XXX2,REG
  221.         else
  222.           ;
  223.           ; See if P1 is of form "ST(i)".  CHECK_ST returns with REG = -1
  224.           ; if not, else REG = i (i from 0 to 7).  If of ST(i) form, assume
  225.           ; P2 is ST (ie. operands are "ST(i),ST".  Use ESC_REG for ESC
  226.           ; sequence.
  227.           ; Example: "FSUB ST(3),ST" - Subtract top of stack from register
  228.           ;                            three (the fourth element down the
  229.           ;                            stack) and leave result in register 3.
  230.           ;
  231.           CHECK_ST P1
  232.           NOTZERO = REG + 1
  233.           if NOTZERO
  234.                   ESC_REG XXX1,REG
  235.           else
  236.             ;
  237.             ; See if P1 indecates operation is "SHORT" real type.  If so,
  238.             ; then P2 is address of source/destination and XXX3 sets up
  239.             ; SHORT version of operation requested.
  240.             ; Example: "FMUL SHORT VECTOR[SE]" - Multiply 32 bit number
  241.             ;          found in memory at VECTOR offset from DS:SI address
  242.             ;          by top of 8087 stack and leave result on top of stack
  243.             ;
  244.             ifidn <P1>,<SHORT>
  245.                   ESC XXX3,P2
  246.                   CHK_CONC              ; Insert non-concurrent WAIT?
  247.             else
  248.             ifidn <P1>,<short>
  249.                   ESC XXX3,P2
  250.                   CHK_CONC              ; Insert non-concurrent WAIT?
  251.             else
  252.               ;
  253.               ; See if P1 indecates a "LONG" real type.  If so, P2 is
  254.               ; source/destination address and XXX4 is LONG opcode.
  255.               ; Example: "FDIV LONG [BP].ID_NUMB" - Divide top of stack
  256.               ;          by 64 bit number found at SS:BP + ID_NUMB
  257.               ;          in memory.  Leave result on top of 8087 stack
  258.               ;
  259.               ifidn <P1>,<LONG>
  260.                 ESC XXX4,P2
  261.                 CHK_CONC                ; Insert non-concurrent WAIT?
  262.               else
  263.               ifidn <P1>,<long>
  264.                 ESC XXX4,P2
  265.                 CHK_CONC                ; Insert non-concurrent WAIT?
  266.               else
  267.                 ;
  268.                 ; See if P1 indicates "TEMP" real type.  If so, P2 is
  269.                 ; source/destination and XXX2 is TEMP opcode.
  270.                 ; Example: "FLD TEMP INTERMEDIATE" - Load 80-bit temporary
  271.                 ;          real number from memory address INTERMEDIATE
  272.                 ;          onto top of 8087 stack
  273.                 ; 
  274.                 ifidn <P1>,<TEMP>
  275.                   ESC XXX2,P2
  276.                   CHK_CONC              ; Insert non-concurrent WAIT?
  277.                 else
  278.                 ifidn <P1>,<temp>
  279.                   ESC XXX2,P2
  280.                   CHK_CONC              ; Insert non-concurrent WAIT?
  281.                 else
  282.                   ;
  283.                   ; If none of above, assume operation is of type "ST(i)"
  284.                   ; and take appropriate action
  285.                   ; Example: "FFREE ST(2)" - Free register 2 in 8087
  286.                   ;
  287.                   REG = 1
  288.                   ESC_REG XXX2,REG
  289.                 endif
  290.               endif
  291.             endif
  292.           endif   
  293.         endif
  294.       endif
  295. endif
  296. endif
  297. endif
  298. endif
  299. endm
  300.  
  301. ;**********************************************************************;
  302. ;                                                                      ;
  303. ;       INT_SIZE - For all integer operations, determine proper        ;
  304. ;                  parameters to use in ESC sequence                   ;
  305. ;                                                                      ;
  306. ;**********************************************************************;
  307.  
  308. INT_SIZE macro P1,P2,XXX_S,XXX_W,XXX_L
  309.  
  310.         ;
  311.         ; Do "WORD" integer operation
  312.         ; Example: "FIMUL WORD PULSE_CNT[SI]" - Multiply 16 bit integer
  313.         ;          value found at (DS:SI + PULSE_CNT) by top of stack
  314.         ;          and leave result on top of stack
  315.         ;
  316.         ifidn <P1>,<WORD>
  317.           ESC XXX_W,P2
  318.         else
  319.         ifidn <P1>,<word>
  320.           ESC XXX_W,P2
  321.         else
  322.           ;
  323.           ; Do "SHORT" integer operation.
  324.           ; Example: "FISUB SHORT [BX].ANGLE" - Subtract 32 bit integer at
  325.           ;          (SP:BX + ANGLE) in main memory from top of stack and
  326.           ;          leave result on top of stack
  327.           ;
  328.           ifidn <P1>,<SHORT>
  329.             ESC XXX_S,P2
  330.           else
  331.           ifidn <P1>,<short>
  332.             ESC XXX_S,P2
  333.           else
  334.             ;
  335.             ; Do "LONG" integer operation
  336.             ; Example: "FILD LONG POS_LABEL" - Load 64-bit integer onto top
  337.             ;          of stack from main memory at POS_LABEL
  338.             ;
  339.             ifidn <P1>,<LONG>
  340.               ESC XXX_L,P2
  341.             else
  342.             ifidn <P1>,<long>
  343.               ESC XXX_L,P2
  344.             else
  345.               ERROR IN macro !!!
  346.             endif
  347.           endif
  348.         endif
  349.   endif
  350.   endif
  351.   endif
  352.   CHK_CONC        ; Insert non-concurrent WAIT?
  353. endm
  354.  
  355.  
  356. ;**********************************************************************;
  357. ;*                                                                     ;
  358. ;*                DEFINE ALL 8087 MNEMONICS HERE                       ;
  359. ;*                    (in alphabetical order)                          ;
  360. ;*                                                                     ;
  361. ;**********************************************************************;
  362.  
  363.  
  364.  
  365. FABS    macro               ; Absolute value - no operands
  366.         WAIT                ; Synchronization cmd
  367.         ESC 0CH,CX
  368. endm
  369.  
  370. FADD    macro     P1,P2     ; Add real - //source/destination,source
  371.                             ;       //ST,ST(i)/ST(i),ST/short-real/long-real
  372.         ifb <P1>            ; If no parameters, classical stack - discard
  373.                             ;   operands
  374.                   FADDP ST(1),ST
  375.         else
  376.                   WAIT      ; Synchronization cmd
  377.                   CHOOSE_4 P1,P2,20H,00H,00H,20H
  378.         endif
  379. endm
  380.  
  381. FADDP   macro     P1,P2     ; Add real and pop - destination, source
  382.                             ;       ST(i),ST
  383.         WAIT                ; Synchronization cmd
  384.         CHOOSE_4 P1,,30H
  385. endm
  386.  
  387. FBLD    macro     P1        ; Packed decimal (BCD) load - source
  388.                             ;     packed-decimal
  389.         WAIT                ; Synchronization cmd
  390.         ESC 3CH,P1
  391. endm
  392.  
  393. FBSTP   macro     P1        ; Packed decimal (BCD) store and pop - destination
  394.                             ;         packed-decimal
  395.         WAIT                ; Synchronization cmd
  396.         ESC 3EH,P1
  397. endm
  398.  
  399. FCHS    macro               ; Change sign - No operands
  400.         WAIT                ; Synchronization cmd
  401.         ESC 0CH,AX
  402. endm
  403.  
  404. FCLEX   macro               ; Clear exceptions - no operands
  405.         WAIT                ; Synchronization cmd
  406.         FNCLEX              ;
  407. endm
  408.  
  409. FCOM    macro     P1,P2     ; Compare real - //source
  410.                             ;        //ST(i)/short-real/long-real
  411.         WAIT                ; Synchronization cmd
  412.         CHOOSE_4 P1,P2,02H,,02H,22H
  413. endm
  414.  
  415. FCOMP   macro     P1,P2     ; Compare real and pop - //source
  416.                             ;       //ST(i)/short-real/long-real
  417.         WAIT                ; Synchronization cmd
  418.         CHOOSE_4 P1,P2,03H,,03H,23H
  419. endm
  420.  
  421. FCOMPP  macro               ; Compare real and pop twice - no operands
  422.         WAIT                ; Synchronization cmd
  423.         ESC 33H,CX
  424. endm
  425.  
  426. FDECSTP macro               ; Decrement stack pointer - no operands
  427.         WAIT                ; Synchronization cmd
  428.         ESC 0EH,SI
  429. endm
  430.  
  431. FDISI   macro               ; Disable interrupts - no operands
  432.         WAIT                ; Synchronization cmd
  433.         FNDISI              ;
  434. endm
  435.  
  436. FDIV    macro     P1,P2     ; Divide real - //source/destination,source
  437.                             ;     //ST(i),ST/short-real/long-real
  438.         ifb <P1>            ; If no parameters, classical stack -discard
  439.                             ;     operands
  440.                   FDIVP ST(1),ST
  441.         else
  442.                   WAIT      ; Synchronization cmd
  443.                   CHOOSE_4 P1,P2,26H,06H,06H,26H
  444.         endif
  445. endm
  446.  
  447. FDIVP   macro     P1,P2     ; Divide real and pop - destination, source
  448.                             ;       ST(i),ST
  449.         WAIT                ; Synchronization cmd
  450.         CHOOSE_4 P1,,36H
  451. endm
  452.  
  453. FDIVR   macro     P1,P2     ; Divide real reversed - //source/destination,
  454.                             ;    source    //ST,ST(i)/ST(i),ST/short-real/
  455.                             ;    long-real
  456.         ifb <P1>            ; If no parameters, classical stack - discard
  457.                             ;    operands
  458.                   FDIVRP ST(1),ST
  459.         else
  460.                   WAIT      ; Synchronization cmd
  461.                   CHOOSE_4 P1,P2,27H,07H,07H,27H
  462.         endif
  463. endm
  464.  
  465. FDIVRP  macro     P1,P2     ; Divide real reversed and pop - destination,source
  466.                             ;     ST(i),ST
  467.         WAIT                ; Synchronization cmd
  468.         CHOOSE_4 P1,,37H
  469. endm
  470.  
  471. FENI    macro               ; Enable interrupts - no operands
  472.         WAIT                ; Synchronization cmd
  473.         FNENI               ;
  474. endm
  475.  
  476. FFREE   macro     P1        ; Free register - destination
  477.                             ;       ST(i)
  478.         WAIT                ; Synchronization cmd
  479.         CHOOSE_4 P1,,28H
  480. endm
  481.  
  482. FIADD   macro     P1,P2     ; Integer add -source
  483.                             ;      word-integer/short-integer
  484.         WAIT                ; Synchronization cmd
  485.         INT_SIZE P1,P2,10H,30H
  486. endm
  487.  
  488. FICOM   macro     P1,P2     ; Integer compare - source
  489.                             ;     word-integer/short-integer
  490.         WAIT                ; Synchronization cmd
  491.         INT_SIZE P1,P2,12H,32H
  492. endm
  493.  
  494. FICOMP  macro     P1,P2     ; Integer compare and pop
  495.                             ;     word-integer/short-integer
  496.         WAIT                ; Synchronization cmd
  497.         INT_SIZE P1,P2,13H,33H
  498. endm
  499.  
  500. FIDIV   macro     P1,P2     ; Integer divide - source
  501.                             ;      word-integer/short-integer
  502.         WAIT                ; Synchronization cmd
  503.         INT_SIZE P1,P2,16H,36H
  504. endm
  505.  
  506. FIDIVR  macro     P1,P2     ; Integer devide reversed - source
  507.                             ;     word-integer/short-integer
  508.         WAIT                ; Synchronization cmd
  509.         INT_SIZE P1,P2,17H,37H
  510. endm
  511.  
  512. FILD    macro     P1,P2     ; Integer load -source
  513.                             ;     word-integer/short-integer/long-integer
  514.         WAIT                ; Synchronization cmd
  515.         INT_SIZE P1,P2,18H,38H,3DH
  516. endm
  517.  
  518. FIMUL   macro     P1,P2     ; Integer multiply - source
  519.                             ;     word-integer/short-integer
  520.         WAIT                ; Synchronization cmd
  521.         INT_SIZE P1,P2,11H,31H
  522. endm
  523.  
  524. FINCSTP macro               ; Increment stack pointer - no operands
  525.         WAIT                ; Synchronization cmd
  526.         ESC 0EH,DI
  527. endm
  528.  
  529. FINIT   macro               ; Initialize processor - no operands
  530.         WAIT                ; Synchronization cmd
  531.         FNINIT              ;
  532. endm
  533.  
  534. FIST    macro     P1,P2     ; Integer store - destination
  535.                             ;     word-integer/short-integer
  536.         WAIT                ; Synchronization cmd
  537.         INT_SIZE P1,P2,1AH,3AH
  538. endm
  539.  
  540. FISTP   macro     P1,P2     ; Integer store and pop -destination
  541.                             ;     word-integer/short-integer/long-integer
  542.         WAIT                ; Synchronization cmd
  543.         INT_SIZE P1,P2,1BH,3BH,3FH
  544. endm
  545.  
  546. FISUB   macro     P1,P2     ; Integer subtract - source
  547.                             ;     word-integer/short-integer
  548.         WAIT                ; Synchronization cmd
  549.         INT_SIZE P1,P2,14H,34H
  550. endm
  551.  
  552. FISUBR  macro     P1,P2     ; Integer subtract reversed - source
  553.                             ;     word-integer/short-integer
  554.         WAIT                ; Synchronization cmd
  555.         INT_SIZE P1,P2,15H,35H
  556. endm
  557.  
  558. FLD     macro     P1,P2     ; Load real -source
  559.                             ;     ST(i)/short-real/long-real/temp-real
  560.         WAIT                ; Synchronization cmd
  561.         CHOOSE_4 P1,P2,08H,1DH,08H,28H  ; 1DH INDICATES TEMPORARY REAL!!
  562. endm
  563.  
  564. FLDCW   macro     P1        ; Load control word - source
  565.                             ;      2-bytes
  566.         WAIT                ; Synchronization cmd
  567.         ESC 0DH,P1
  568. endm
  569.  
  570. FLDENV  macro     P1        ; Load invironment - source
  571.                             ;    14-bytes
  572.         WAIT                ; Synchronization cmd
  573.         ESC 0CH,P1
  574. endm
  575.  
  576. FLDLG2  macro               ; Load log 2 (base 10) - no operands
  577.         WAIT                ; Synchronization cmd
  578.         ESC 0DH,SP
  579. endm
  580.  
  581. FLDLN2  macro               ; Load log 2 (base e) - no operands
  582.         WAIT                ; Synchronization cmd
  583.         ESC 0DH,BP
  584. endm
  585.  
  586. FLDL2E  macro               ; Load log e (base 2) - no operands
  587.         WAIT                ; Synchronization cmd
  588.         ESC 0DH,DX
  589. endm
  590.  
  591. FLDL2T  macro               ; Load log 10 (base 2) - no operands
  592.         WAIT                ; Synchronization cmd
  593.         ESC 0DH,CX
  594. endm
  595.  
  596. FLDPI   macro               ; Load pi - no operand
  597.         WAIT                ; Synchronization cmd
  598.         ESC 0DH,BX
  599. endm
  600.  
  601. FLDZ    macro               ; Load +0.0 - no operands
  602.         WAIT                ; Synchronization cmd
  603.         ESC 0DH,SI
  604. endm
  605.  
  606. FLD1    macro               ; Load +1.0 - no operands
  607.         WAIT                ; Synchronization cmd
  608.         ESC 0DH,AX
  609. endm
  610.  
  611. FMUL    macro     P1,P2     ; Multiply real - //source/destination,source
  612.                             ;     //ST(i),ST/ST,ST(i)/short-real/long-real
  613.         ifb <P1>            ; If no parameters, classical stack -discard
  614.                             ;     operands
  615.                   FMULP ST(1),ST
  616.         else
  617.                   WAIT      ; Synchronization cmd
  618.                   CHOOSE_4 P1,P2,21H,01H,01H,21H
  619.         endif
  620. endm
  621.  
  622. FMULP   macro     P1,P2     ; Multiply real and pop - destination,source
  623.                             ;    ST(i),ST
  624.         WAIT                ; Synchronization cmd
  625.         CHOOSE_4 P1,,31H
  626. endm
  627.  
  628. FNCLEX  macro               ; Clear exceptions - no wait FCLEX
  629.         ESC 1CH,DX
  630. endm
  631.  
  632. FNDISI  macro               ; Disable interrupts - no wait FDISI
  633.         ESC 1CH,CX          ;
  634. endm
  635.  
  636. FNENI   macro               ; Enable interrupts - no wait FENI
  637.         ESC 1CH,AX
  638. endm
  639.  
  640. FNINIT  macro               ; Initialize processor - no wait FINIT
  641.         ESC 1CH,BX          ;
  642. endm
  643.  
  644. FNOP    macro               ; No operation - no operands
  645.         WAIT                ; Synchronization cmd
  646.         ESC 0AH,AX
  647. endm
  648.  
  649. FNSAVE  macro     P1        ; Save state - destination (No wait FSAVE)
  650.                             ;    94-bytes
  651.         ESC 2EH,P1          ;
  652. endm
  653.  
  654. FNSTCW  macro     P1        ; Store control word - destination (No wait FSTCW)
  655.                             ;     2-bytes
  656.         ESC 0FH,P1          ;
  657. endm
  658.  
  659. FNSTENV macro     P1        ; Store environment - destination (No wait FSTENV)
  660.                             ;    14-bytes
  661.         ESC 0EH,P1          ;
  662. endm
  663.  
  664. FNSTSW  macro     P1        ; Store status word - destination (No wait FSTSW)
  665.                             ;     2-bytes
  666.         ESC 2FH,P1          ;
  667. endm
  668.  
  669. FPATAN  macro               ; Partial arctangent - no operands
  670.         WAIT                ; Synchronization cmd
  671.         ESC 0EH,BX
  672. endm
  673.  
  674. FPREM   macro               ; Partial remainder - no operands
  675.         WAIT                ; Synchronization cmd
  676.         ESC 0FH,AX
  677. endm
  678.  
  679. FPTAN   macro               ; Partial tangent - no operands
  680.         WAIT                ; Synchronization cmd
  681.         ESC 0EH,DX
  682. endm
  683.  
  684. FRNDINT macro               ; Round to integer - no operands
  685.         WAIT                ; Synchronization cmd
  686.         ESC 0FH,SP
  687. endm
  688.  
  689. FRSTOR  macro     P1        ; Restore saved state - source
  690.                             ;    94-bytes
  691.         WAIT                ; Synchronization cmd
  692.         ESC 2CH,P1
  693. endm
  694.  
  695. FSAVE   macro     P1        ; Save state - destination
  696.                             ;     94-bytes
  697.         WAIT                ; Synchronization cmd
  698.         FNSAVE P1           ;
  699. endm
  700.  
  701. FSCALE  macro               ; Scale - no operands
  702.         WAIT                ; Synchronization cmd
  703.         ESC 0FH,BP
  704. endm
  705.  
  706. FSQRT   macro               ; Square root - no operands
  707.         WAIT                ; Synchronization cmd
  708.         ESC 0FH,DX
  709. endm
  710.  
  711. FST     macro     P1,P2     ; Store real -destination
  712.                             ;     ST(i)/short-real/long-real
  713.         WAIT                ; Synchronization cmd
  714.         CHOOSE_4 P1,P2,2AH,,0AH,2AH
  715. endm
  716.  
  717. FSTCW   macro     P1        ; Store control word - destination
  718.                             ;     2-bytes
  719.         WAIT                ; Synchronization cmd
  720.         FNSTCW P1           ;
  721. endm
  722.  
  723. FSTENV  macro     P1        ; Store environment - destination
  724.                             ;    14-bytes
  725.         WAIT                ; Synchronization cmd
  726.         FNSTENV   P1        ;
  727. endm
  728.  
  729. FSTP    macro     P1,P2     ; Store real and pop - destination
  730.                             ;    ST(i)/short-real/long-real/temp-real
  731.         WAIT                ; Synchronization cmd
  732.         CHOOSE_4 P1,P2,2BH,1FH,0BH,2BH   ; 1FH INDICATES TEMPORARY REAL!!
  733. endm
  734.  
  735. FSTSW   macro     P1        ; Store status word -destination
  736.                             ;    2-bytes
  737.         WAIT                ; Synchronization cmd
  738.         FNSTSW    P1        ;
  739. endm
  740.  
  741. FSUB    macro     P1,P2     ; Subtract real - //source/destination,source
  742.                             ;    //ST,ST(i)/ST(i),ST/short-real/long-real
  743.         ifb <P1>            ; If no parameters, classical stack -discard
  744.                             ;    operands
  745.                   FSUBP ST(1),ST
  746.         else
  747.                   WAIT      ; Synchronization cmd
  748.                   CHOOSE_4 P1,P2,24H,04H,04H,24H
  749.         endif
  750. endm
  751.  
  752. FSUBP   macro     P1,P2     ; Subtract real and pop -destination, source
  753.                             ;    ST(i),ST
  754.         WAIT                ; Synchronization cmd
  755.         CHOOSE_4 P1,,34H
  756. endm
  757.  
  758. FSUBR   macro     P1,P2     ; Subtract real reversed - //source/destination/so
  759.                             ;     //ST,ST(i)/ST(i),ST/short-real/long-real
  760.         ifb <P1>            ; If no parameters, classical stack - discard
  761.                             ;    operands
  762.                   FSUBRP ST(1),ST
  763.         else
  764.                   WAIT      ; Synchronization cmd
  765.                   CHOOSE_4 P1,P2,25H,05H,05H,25H
  766.         endif
  767. endm
  768.  
  769. FSUBRP  macro     P1,P2     ; Subtract real reversed and pop - dest, source
  770.                             ;    ST(i),ST
  771.         WAIT                ; Synchronization cmd
  772.         CHOOSE_4 P1,,35H
  773. endm
  774.  
  775. FTST    macro               ; Test stack top against +0.0 - no operands
  776.         WAIT                ; Synchronization cmd
  777.         ESC 0CH,SP
  778. endm
  779.  
  780. FWAIT   macro               ; (CPU) Wait while 8087 is busy - no operands
  781.         WAIT                ; NOTE: CPU instruction, not escape code
  782. endm
  783.  
  784. FXAM    macro               ; Examine stack top - no operands
  785.         WAIT                ; Synchronization cmd
  786.         ESC 0CH,BP
  787. endm
  788.  
  789. FXCH    macro     P1        ; Exchange registers - //destination
  790.                             ;    //ST(i)
  791.         WAIT                ; Synchronization cmd
  792.         CHOOSE_4 P1,,09H
  793. endm
  794.  
  795. FXTRACT macro               ; Extract exponent and significand - no operands
  796.         WAIT                ; Synchronization cmd
  797.         ESC 0EH,SP
  798. endm
  799.  
  800. FYL2X   macro               ; Y * log X (base 2) - no operands
  801.         WAIT                ; Synchronization cmd
  802.         ESC 0EH,CX
  803. endm
  804.  
  805. FYL2XP1 macro               ; Y * log (X+1) (base 2) - no operands
  806.         WAIT                ; Synchronization cmd
  807.         ESC 0FH,CX
  808. endm
  809.  
  810. F2XM1   macro               ; (2^^X - 1) - no operands
  811.         WAIT                ; Synchronization cmd
  812.         ESC 0EH,AX
  813. endm
  814.  
  815. endif
  816.  
  817. AUTOSYNC=1                  ; Initialize M8087 to automatic synchronization
  818. ndm
  819.  
  820. endif
  821.  
  822. AUTOSYNC=1                  ; Initialize M8087 to automatic synchronization
  823.